package org.bluedream.core.module.sys.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.aspectj.weaver.ast.Or;
import org.bluedream.comm.base.TreeServiceImpl;
import org.bluedream.core.module.entity.depItem.DepItem;
import org.bluedream.core.module.service.depItem.DepItemService;
import org.bluedream.core.module.sys.dao.OrganizationDao;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.module.sys.entity.Menu;
import org.bluedream.core.module.sys.entity.org.OrgRelation;
import org.bluedream.core.module.sys.entity.Organization;
import org.bluedream.core.module.sys.service.org.OrgRelationService;
import org.bluedream.core.utils.SpringUtil;
import org.bluedream.core.utils.UserUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@DS("master")
@Transactional(
        readOnly = true
)
public class OrganizationService extends TreeServiceImpl<OrganizationDao, Organization> implements IService<Organization> {
    private static final Logger logger = LoggerFactory.getLogger(OrganizationService.class);

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private OrgRelationService orgRelationService;

    /**
     * 不做任何条件判断，返回所有菜单数据
     * @return
     */
    public List<Organization> selectAll(){
        return baseMapper.selectAll(super.orderByString(new Organization()));
    }

    /**
     * 返回所有 parent_codes 字段中包含当前登录组织的组织明细
     * @return
     */
    public List<Organization> selectListByLoginOrg(){
        if (UserUtil.isSystem()){
            return this.selectAll();
        }else {
            QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
            String orgId = UserUtil.getLoginOrgCode();
            queryWrapper.like("parent_codes" , orgId).or().eq("id" , orgId);
            queryWrapper.last("order by " + super.orderByString(new Organization()));
            return this.selectListByLoginOrg(queryWrapper);
        }
    }

    public List<Organization> selectListByLoginOrg(QueryWrapper<Organization> queryWrapper){
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 返回 某角色已经选择的组织信息
     * @param roleId
     * @return
     */
    public List<Organization> selectListByRole(String roleId){
        return baseMapper.selectListByRole(roleId , super.orderByString(new Organization()));
    }

    /**
     * 获取树结构数据
     * @param excludeCode 排除的code
     * @param isShowCode 是否显示编码（true or 1：显示在左侧；2：显示在右侧；false or null：不显示）
     * @return
     */
    public List<Map<String , Object>>  treeData(String excludeCode , String isShowCode){
        if (UserUtil.isSystem()){
            return super.treeData(excludeCode , isShowCode , new Organization());
        }else {
            QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
            String orgId = UserUtil.getLoginOrgCode();
            queryWrapper.like("parent_codes" , orgId).or().eq("id" , orgId);
            queryWrapper.last("order by " + super.orderByString(new Organization()));
            return super.treeData(excludeCode , isShowCode , new Organization() , queryWrapper);
        }
    }

    public List<Map<String , Object>> treeData(String excludeCode , String isShowCode , List<Organization> list){
        return super.treeData(excludeCode , isShowCode , new Organization() , list);
    }

    public List<Map<String , Object>> treeData(String excludeCode , String isShowCode , List<Organization> source , List<Organization> isChecked){
        return super.treeData(excludeCode , isShowCode , source , isChecked);
    }

    /**
     * 创建并初始化下一节点信息
     * 0.前端数据仅包含：parentCode、id
     * 1.通过parentCode
     *  1.1 获取父级节点最末节点对象last数据。默认返回null
     *  1.2 获取新的父级节点company对象，默认id = “0”
     *  1.3 如果id ！= null ， 初始化company对象
     * 2.新增节点：初始化treeCode：如果 last不为空，则+1。如果为空，但是父级对象不为空，则父级treeCode+ 001
     * 3.编辑节点：如果父级节点无变化，则不更新treeSort排序数据，否则更新
     * @param company
     * @return
     */
    public Organization createNextNode(Organization company){
        company.setParentCode();
        return super.createNextNode(company , "code" , "tree_sorts" , "tree_sort");
    }

    public IPage<Organization> findPage(Organization company){
        return super.findPage(company , null , "tree_Sorts" , "tree_Sort");
    }

    @Transactional(
            readOnly = false,
            rollbackFor = Exception.class
    )
    public boolean save(Organization entity) {
        try {
            boolean isNewRecord = super.getIsNewRecord(entity , "code" , "getTreeCode");
            boolean flag;
            if (EmptyUtil.isNoEmpty(entity.getParent())){
                if (entity.getParent().getId().equals("")){
                    Organization p1 = entity.getParent();
                    p1.setId("");
                    entity.setParent(p1);
                }
            }
//            entity.setIsNewRecord(isNewRecord);
            flag = super.save(entity);
            // 新增组织 同时将组织信息 COPY 到 部门表。

/*
            flag = copyToDepItem(entity , isNewRecord);
*/

            return flag;
        }catch (Exception e){
            e.printStackTrace();
            logger.error("保存菜单信息失败，错误信息：" + e.getMessage());
            //todo:@Transactional和try catch捕获异常会让注解失效
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
    }

    @Override
    public Organization getById(Serializable id) {
        if (EmptyUtil.isEmpty(id)){
            return new Organization();
        }else {
            Organization company = super.getById(id);
            if (!"0".equals(company.getParentCode())){
                company.setParent(super.getById(company.getParentCode()));
            }
            return company;
        }
    }

    public String getSystemOrganizationId() throws NullPointerException{
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code" , "0");
        return super.getOne(queryWrapper).getId();
    }


    public Organization getOrganization(OrgRelation orgRelation){
        QueryWrapper<OrgRelation> qw = new QueryWrapper<>(orgRelation);
        orgRelation = orgRelationService.getOne(qw);
        if (EmptyUtil.isNoEmpty(orgRelation)){
            return  this.getById(orgRelation.getOrgId());
        }
        return null;
    }
}
